<template>
  <div class="image-preview-container" :class="{ 'thumbnail-mode': thumbnailMode }">
    <!-- 主图片显示 -->
    <el-image
      :src="currentImageSrc"
      :fit="fit"
      :style="imageStyle"
      :preview-src-list="previewList"
      :initial-index="currentIndex"
      :z-index="zIndex"
      :preview-teleported="true"
      :loading="loading"
      :lazy="lazy"
      @load="handleImageLoad"
      @error="handleImageError"
      @switch="handleImageSwitch"
      class="main-image"
    >
      <!-- 加载状态 -->
      <template #placeholder>
        <div class="image-placeholder">
          <el-icon class="loading-icon"><Loading /></el-icon>
          <span class="loading-text">加载中...</span>
        </div>
      </template>
      
      <!-- 错误状态 -->
      <template #error>
        <div class="image-error" @click="retryLoad">
          <el-icon class="error-icon"><Picture /></el-icon>
          <span class="error-text">{{ errorRetryCount > 0 ? '点击重试' : '加载失败' }}</span>
          <el-button 
            v-if="errorRetryCount > 0" 
            type="primary" 
            size="small" 
            @click.stop="retryLoad"
            class="retry-btn"
          >
            重新加载
          </el-button>
        </div>
      </template>
    </el-image>
    
    <!-- 缩略图列表 -->
    <div v-if="showThumbnails && imageList.length > 1" class="thumbnail-list">
      <div 
        v-for="(img, index) in imageList" 
        :key="index"
        class="thumbnail-item"
        :class="{ active: index === currentIndex }"
        @click="switchImage(index)"
      >
        <el-image
          :src="img.thumb || img.src"
          fit="cover"
          class="thumbnail-image"
          :loading="loading"
        >
          <template #error>
            <div class="thumbnail-error">
              <el-icon><Picture /></el-icon>
            </div>
          </template>
        </el-image>
        <div class="thumbnail-overlay">
          <span class="thumbnail-index">{{ index + 1 }}</span>
        </div>
      </div>
    </div>
    
    <!-- 图片信息 -->
    <div v-if="showInfo && currentImage" class="image-info">
      <div class="info-item">
        <span class="info-label">尺寸:</span>
        <span class="info-value">{{ currentImage.width || '未知' }} × {{ currentImage.height || '未知' }}</span>
      </div>
      <div class="info-item">
        <span class="info-label">大小:</span>
        <span class="info-value">{{ formatFileSize(currentImage.size) }}</span>
      </div>
      <div class="info-item" v-if="currentImage.name">
        <span class="info-label">名称:</span>
        <span class="info-value">{{ currentImage.name }}</span>
      </div>
    </div>
    
    <!-- 操作按钮 -->
    <div v-if="showActions" class="image-actions">
      <el-button-group>
        <el-button 
          v-if="imageList.length > 1" 
          @click="prevImage" 
          :disabled="currentIndex === 0 && !loop"
          size="small"
        >
          <el-icon><ArrowLeft /></el-icon>
        </el-button>
        <el-button @click="downloadImage" size="small">
          <el-icon><Download /></el-icon>
        </el-button>
        <el-button @click="copyImageUrl" size="small">
          <el-icon><CopyDocument /></el-icon>
        </el-button>
        <el-button 
          v-if="imageList.length > 1" 
          @click="nextImage" 
          :disabled="currentIndex === imageList.length - 1 && !loop"
          size="small"
        >
          <el-icon><ArrowRight /></el-icon>
        </el-button>
      </el-button-group>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { 
  Loading, 
  Picture, 
  ArrowLeft, 
  ArrowRight, 
  Download, 
  CopyDocument 
} from '@element-plus/icons-vue'
import { isExternal } from '@/utils/validate'

// Props定义
const props = defineProps({
  // 图片源，支持字符串或数组
  src: {
    type: [String, Array],
    default: ''
  },
  // 宽度
  width: {
    type: [Number, String],
    default: 200
  },
  // 高度
  height: {
    type: [Number, String],
    default: 200
  },
  // 图片适应方式
  fit: {
    type: String,
    default: 'cover',
    validator: (value) => ['fill', 'contain', 'cover', 'none', 'scale-down'].includes(value)
  },
  // 是否懒加载
  lazy: {
    type: Boolean,
    default: true
  },
  // 是否显示缩略图
  showThumbnails: {
    type: Boolean,
    default: false
  },
  // 是否显示图片信息
  showInfo: {
    type: Boolean,
    default: false
  },
  // 是否显示操作按钮
  showActions: {
    type: Boolean,
    default: false
  },
  // 缩略图模式
  thumbnailMode: {
    type: Boolean,
    default: false
  },
  // 是否循环播放
  loop: {
    type: Boolean,
    default: true
  },
  // 预览层级
  zIndex: {
    type: Number,
    default: 2000
  },
  // 错误重试次数
  maxRetry: {
    type: Number,
    default: 3
  }
})

// Emits定义
const emit = defineEmits([
  'load',
  'error', 
  'switch',
  'download',
  'copy'
])

// 响应式数据
const loading = ref(false)
const currentIndex = ref(0)
const errorRetryCount = ref(props.maxRetry)
const imageLoadStates = ref(new Map())

// 计算属性
const imageList = computed(() => {
  if (!props.src) return []
  
  if (Array.isArray(props.src)) {
    return props.src.map(item => {
      if (typeof item === 'string') {
        return { src: processImageUrl(item) }
      }
      return {
        ...item,
        src: processImageUrl(item.src),
        thumb: item.thumb ? processImageUrl(item.thumb) : undefined
      }
    })
  }
  
  // 字符串格式，支持逗号分隔
  const srcList = props.src.split(',')
  return srcList.map(src => ({ src: processImageUrl(src.trim()) }))
})

const currentImage = computed(() => {
  return imageList.value[currentIndex.value] || null
})

const currentImageSrc = computed(() => {
  return currentImage.value?.src || ''
})

const previewList = computed(() => {
  return imageList.value.map(img => img.src)
})

const imageStyle = computed(() => {
  const width = typeof props.width === 'string' ? props.width : `${props.width}px`
  const height = typeof props.height === 'string' ? props.height : `${props.height}px`
  return {
    width,
    height
  }
})

// 方法
const processImageUrl = (url) => {
  if (!url) return ''
  if (isExternal(url)) return url
  return import.meta.env.VITE_APP_BASE_API + url
}

const handleImageLoad = (event) => {
  loading.value = false
  errorRetryCount.value = props.maxRetry
  
  // 获取图片尺寸信息
  if (currentImage.value && event.target) {
    currentImage.value.width = event.target.naturalWidth
    currentImage.value.height = event.target.naturalHeight
  }
  
  emit('load', event)
}

const handleImageError = (event) => {
  loading.value = false
  emit('error', event)
}

const handleImageSwitch = (index) => {
  currentIndex.value = index
  emit('switch', index)
}

const retryLoad = () => {
  if (errorRetryCount.value > 0) {
    errorRetryCount.value--
    loading.value = true
    // 强制重新加载图片
    nextTick(() => {
      loading.value = false
    })
  }
}

const switchImage = (index) => {
  if (index >= 0 && index < imageList.value.length) {
    currentIndex.value = index
  }
}

const prevImage = () => {
  if (currentIndex.value > 0) {
    currentIndex.value--
  } else if (props.loop) {
    currentIndex.value = imageList.value.length - 1
  }
}

const nextImage = () => {
  if (currentIndex.value < imageList.value.length - 1) {
    currentIndex.value++
  } else if (props.loop) {
    currentIndex.value = 0
  }
}

const downloadImage = async () => {
  if (!currentImageSrc.value) return
  
  try {
    const response = await fetch(currentImageSrc.value)
    const blob = await response.blob()
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = currentImage.value?.name || `image_${Date.now()}.jpg`
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    
    ElMessage.success('图片下载成功')
    emit('download', currentImage.value)
  } catch (error) {
    ElMessage.error('图片下载失败')
  }
}

const copyImageUrl = async () => {
  if (!currentImageSrc.value) return
  
  try {
    await navigator.clipboard.writeText(currentImageSrc.value)
    ElMessage.success('图片链接已复制到剪贴板')
    emit('copy', currentImageSrc.value)
  } catch (error) {
    ElMessage.error('复制失败')
  }
}

const formatFileSize = (bytes) => {
  if (!bytes) return '未知'
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(1024))
  return Math.round(bytes / Math.pow(1024, i) * 100) / 100 + ' ' + sizes[i]
}

// 监听src变化，重置状态
watch(() => props.src, () => {
  currentIndex.value = 0
  errorRetryCount.value = props.maxRetry
}, { immediate: true })
</script>

<style lang="scss" scoped>
@import '@/assets/styles/variables.module.scss';

.image-preview-container {
  position: relative;
  display: inline-block;
  
  &.thumbnail-mode {
    .main-image {
      border-radius: $border-radius-small;
    }
  }
  
  .main-image {
    border-radius: $border-radius-base;
    background-color: $gray-100;
    box-shadow: $box-shadow-light;
    border: 1px solid $gray-200;
    overflow: hidden;
    transition: $transition-base;
    cursor: pointer;
    
    &:hover {
      box-shadow: $box-shadow-base;
      border-color: $primary;
      transform: translateY(-2px);
    }
    
    :deep(.el-image__inner) {
      transition: all 0.3s ease;
      
      &:hover {
        transform: scale(1.02);
      }
    }
  }
  
  .image-placeholder {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, $gray-50, $gray-100);
    color: $gray-400;
    
    .loading-icon {
      font-size: 24px;
      margin-bottom: 8px;
      animation: rotate 1s linear infinite;
    }
    
    .loading-text {
      font-size: 12px;
    }
  }
  
  .image-error {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, $gray-50, $gray-100);
    color: $gray-400;
    cursor: pointer;
    transition: $transition-base;
    
    &:hover {
      color: $primary;
      background: linear-gradient(135deg, $gray-100, $gray-200);
    }
    
    .error-icon {
      font-size: 24px;
      margin-bottom: 8px;
    }
    
    .error-text {
      font-size: 12px;
      margin-bottom: 8px;
    }
    
    .retry-btn {
      font-size: 11px;
      padding: 4px 8px;
    }
  }
  
  .thumbnail-list {
    display: flex;
    gap: 8px;
    margin-top: 12px;
    padding: 8px;
    background: $gray-50;
    border-radius: $border-radius-base;
    overflow-x: auto;
    
    .thumbnail-item {
      position: relative;
      flex-shrink: 0;
      width: 60px;
      height: 60px;
      border-radius: $border-radius-small;
      overflow: hidden;
      cursor: pointer;
      transition: $transition-base;
      border: 2px solid transparent;
      
      &:hover {
        transform: scale(1.05);
        border-color: $primary;
      }
      
      &.active {
        border-color: $primary;
        box-shadow: 0 0 0 2px rgba($primary, 0.2);
      }
      
      .thumbnail-image {
        width: 100%;
        height: 100%;
      }
      
      .thumbnail-error {
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;
        height: 100%;
        background: $gray-200;
        color: $gray-400;
        font-size: 16px;
      }
      
      .thumbnail-overlay {
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        background: linear-gradient(transparent, rgba(0, 0, 0, 0.6));
        color: white;
        padding: 4px;
        
        .thumbnail-index {
          font-size: 10px;
          font-weight: 500;
        }
      }
    }
  }
  
  .image-info {
    margin-top: 12px;
    padding: 12px;
    background: $gray-50;
    border-radius: $border-radius-base;
    font-size: 12px;
    
    .info-item {
      display: flex;
      justify-content: space-between;
      margin-bottom: 4px;
      
      &:last-child {
        margin-bottom: 0;
      }
      
      .info-label {
        color: $gray-600;
        font-weight: 500;
      }
      
      .info-value {
        color: $gray-800;
      }
    }
  }
  
  .image-actions {
    margin-top: 12px;
    display: flex;
    justify-content: center;
    
    .el-button-group {
      .el-button {
        border-radius: $border-radius-small;
        
        &:hover {
          transform: translateY(-1px);
        }
      }
    }
  }
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

// 响应式设计
@media (max-width: 768px) {
  .image-preview-container {
    .thumbnail-list {
      .thumbnail-item {
        width: 50px;
        height: 50px;
      }
    }
    
    .image-actions {
      .el-button-group {
        .el-button {
          padding: 6px 8px;
          font-size: 12px;
        }
      }
    }
  }
}
</style>
